package com.learn.english.config;

import com.learn.english.constants.JwtConstants;
import com.learn.english.service.RedisService;
import com.learn.english.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.util.*;

/**
 * @author TISNIW
 * @version 1.0
 * @desc
 */
@Component
public class JwtAuthInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private RedisService redisService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws IOException {
        // 获取请求URI，跳过登录和注册接口以及Swagger相关路径
        String uri = request.getRequestURI();
        if (uri.contains("/login/") || uri.contains("/register") || uri.contains("/menu") || uri.contains("/banner")
                || uri.contains("/swagger-ui") || uri.contains("/v3/api-docs") || uri.contains("/swagger-resources")
                || uri.equals("/swagger-ui.html") || uri.equals("/video/**")) {
            return true;
        }

        String token = request.getHeader("Authorization");

        if (token == null || token.isEmpty()) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json");
            response.getWriter().write("{\"code\":401,\"message\":\"缺少Token\"}");
            return false;
        }

        try {
            // 移除Bearer前缀
            if (token.startsWith("Bearer ")) {
                token = token.substring(7);
            }

            Claims claims = JwtUtils.parseToken(token, JwtConstants.SECRET);

            // 验证 Token 是否在 Redis 中存在（防止吊销）
            Long userId = JwtUtils.getUserIdFromClaims(claims);
            String redisKey = JwtConstants.TOKEN_REDIS_PREFIX + userId;
            String cachedToken = redisService.getCacheObject(redisKey, String.class);
            if (cachedToken == null || !cachedToken.contains(token)) {
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.setContentType("application/json");
                response.getWriter().write("{\"code\":401,\"message\":\"Token无效或已过期\"}");
                return false;
            }

            // 将用户信息放入 request，供 Controller 使用
            request.setAttribute("userId", userId);
            request.setAttribute("loginUser", JwtUtils.getLoginUserFromClaims(claims));

            return true;

        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            response.setContentType("application/json");
            response.getWriter().write("{\"code\":401,\"message\":\"Token解析失败: " + e.getMessage() + "\"}");
            return false;
        }
    }
}
